import Constant, { Uri } from '../constant/Constants';
import ProtocolRequest from '../protocol/request/ProtocolRequest';
import ProtocolResponse from '../protocol/response/ProtocolResponse';
import CodecUtil from './CodecUtil';
import DateUtil from './DateUtil';
import Util from './Util';
import UniUitl from './UniUtil'
import LoggerUtil from './LoggerUtil';
import { ErrorCode } from '../constant/ErrorCode';
import { CacheKeys } from '../constant/CacheKeys';
import UniUtil from './UniUtil';
import { UserInfo } from '@/model/UserInfo';
export default class Http {

    public static request<R, T>(url: string, param: R, ins: T, showLoading: boolean = true, showSuccess: boolean = false, showError: boolean = true): Promise<T> {

        //登陆状态校验
        let success = Http.checkAuth(url);
        if (!success) {
            return;
        }
        let request = Http.newProtocolRequest();

        if (!Util.isEmpty(param)) {
            request.setData(JSON.stringify(param));
        }
        LoggerUtil.info("http req url:{} param:{}", url, JSON.stringify(request));

        let data = CodecUtil.encrypt(param);
        request.setData(data);

        let sign = CodecUtil.sign(request);
        request.setSign(sign);
        let promise = new Promise<T>(resolve => {
            let options = Http.newRequestOptions(url, request, resolve, showLoading);
            options.success = async function (res) {
                let response = Http.newSuccessResponse(res.data);
                LoggerUtil.info("http res url:{} param:{}", url, JSON.stringify(response));
                if (showLoading) {
                    UniUtil.hideLoading();
                }
                if (response.getCode() != 0) {
                    if (response.getCode() == ErrorCode.REQUEST_AUTH_EXPIRED || response.getCode() == ErrorCode.REQUEST_TOKEN_INVALID || response.getCode() == ErrorCode.REQUEST_USER_NOT_EXISTS) {
                        await Util.sleep(1000)
                        UniUitl.removeStorage(CacheKeys.USER_INFO_KEY);
                        Http.toAuthorize();
                        return;
                    }
                    if (showError) {
                        UniUtil.showError({ title: response.getMsg() });
                    }
                    if (ins instanceof ProtocolResponse) {
                        let data = Object.assign(ins, response);
                        resolve(data);
                    } else {
                        resolve(null);
                    }

                } else {
                    if (showSuccess) {
                        UniUitl.showSuccess();
                    }
                    if (ins instanceof ProtocolResponse) {
                        let data = Object.assign(ins, response);
                        resolve(data);
                    } else {
                        if (null == response.getResult()) {
                            resolve(null);
                        } else {
                            let data = Object.assign(ins, response.getResult());
                            resolve(data);
                        }
                    }
                }
            };

            if (showLoading) {
                UniUtil.showLoading();
            }
            uni.request(options)
        });
        return promise;
    }

    static newRequestOptions(url: string, request: ProtocolRequest, resolve: Function, showLoading: boolean) {
        let option: UniApp.RequestOptions =
        {
            url: url,
            method: "POST",
            data: request,
            timeout: 30000,
            fail: function (res) {
                UniUitl.showError({ title: "网络繁忙，稍后再试" });
                resolve(null);
            },
            complete: function () {

            }
            ,
            header: { 'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8' }
        };
        return option;
    }

    private static newSuccessResponse<T>(data: any): ProtocolResponse<T> {
        let that = this;
        let response = Object.assign(new ProtocolResponse<T>(), data);
        return response;
    }

    private static newFailResponse(): ProtocolResponse<any> {
        let response = new ProtocolResponse();
        return response;
    }


    private static newProtocolRequest(): ProtocolRequest {
        let request = new ProtocolRequest();
        request.setTimestamp(DateUtil.now());
        request.setPlatform(uni.getSystemInfoSync().platform);
        let userInfo = UniUitl.getStorage(CacheKeys.USER_INFO_KEY, UserInfo.User)
        if (!Util.isEmpty(userInfo)) {
            request.setUid(userInfo.uid);
            request.setToken(userInfo.token);
        }
        return request;
    }

    private static checkAuth(url: string) {
        if (Uri.unauth_urls.indexOf(url) < 0) {
            let userInfo = UniUitl.getStorage(CacheKeys.USER_INFO_KEY, UserInfo.User);
            if (Util.isEmpty(userInfo)) {
                Http.toAuthorize();
                return false;
            }
        }
        return true;
    }

    private static toAuthorize() {
        LoggerUtil.info("xxxtoAuthorizexxxx");
        UniUitl.navigateTo("/pages/login/login");
    }
}